package com.walter.common.exception;

import com.walter.common.basic.ResultVO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Optional;

/**
 *  全局异常处理
 * @author Walter
 * @date 2025/1/20 上午11:23
 **/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     *  处理参数验证异常 MethodArgumentNotValidException
     * @param request
     * @param ex
     * @return
     */
     @SneakyThrows
     @ExceptionHandler(value = MethodArgumentNotValidException.class)
     public ResultVO handleValidException(HttpServletRequest request, MethodArgumentNotValidException ex) {
         BindingResult bindingResult = ex.getBindingResult();
         FieldError firstFieldError = CollectionUtils.isEmpty(bindingResult.getFieldErrors())?null:bindingResult.getFieldErrors().get(0);
         String exceptionStr = Optional.ofNullable(firstFieldError).map(FieldError::getDefaultMessage).orElse("");
         log.error("[{}] {} [ex] {}", request.getMethod(),"URL:", exceptionStr);
         return ResultVO.fail(exceptionStr);    }

    /**
     *  处理自定义异常:AbstractException
     * @param request
     * @param ex
     * @return
     */
     @ExceptionHandler(value = {AbstractException.class})
     public ResultVO handleAbstractException(HttpServletRequest request, AbstractException ex) {
         String requestURL = "URL地址";
         log.error("[{}] {} [ex] {}", request.getMethod(), requestURL, ex.toString());
         return ResultVO.fail(ex.toString());
     }

    /**
     * 兜底处理：Throwable
     * @param request
     * @param throwable
     * @return
     */
     @ExceptionHandler(value = Throwable.class)
     public ResultVO handleThrowable(HttpServletRequest request, Throwable throwable) {
         //        String requestURL = getUrl(request);
                 log.error("[{}] {} ", request.getMethod(), "URL地址", throwable);
                 return ResultVO.fail(AppHttpCodeEnum.FAIL.getMessage());
     }
}
